#!/usr/bin/env python
# -*- coding: utf-8 -*-

class AbstractNotifier:
    def __init__(self):
        self._listeners = [ ]
    
    def add_listener(self, listener, prefix=''):
        if (listener, prefix) not in self._listeners:
            self._listeners.append((listener, prefix))
    
    def remove_listener(self, listener, prefix=''):
        try:
            self._listeners.remove((listener, prefix))
        except KeyError:
            pass
    
    def _notify_listeners(self, event, data=None):
        for listener, prefix in self._listeners:
            try:
                getattr(listener, 'on_%s_%s' % (prefix, event))(data)
            except AttributeError:
                pass

class ConfigManager:
    def __init__(self, filename):
        self._filename = filename
        self._settings = { }
        self._objects = [ ]
    
    def register(self, object, name):
        if (object, name) not in self._objects:
            self._objects.append((object, name))
    
    def deregister(self, object, name):
        try:
            self._objects.remove((object, name))
        except KeyError:
            pass
    
    def store(self):
        for object, name in self._objects:
            self._settings[name] = object.get_config()
            print 'storing', self._settings[name], 'from %s' % name
        try:
            f = open(self._filename, 'w')
            f.write(str(self._settings))
            f.close()
        except:
            pass
    
    def restore(self):
        try:
            f = open(self._filename, 'r')
            self._settings = eval(f.read())
            f.close
        except:
            for object, name in self._objects:
                print 'restoring %s to default' % name
                object.set_default_config()
            return
        for object, name in self._objects:
            try:
                object.set_config(self._settings[name])
                print 'restoring %s with' % name, self._settings[name]
            except KeyError:
                print 'restoring %s to default' % name
                object.set_default_config()
    